package com.calabar.query;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.calabar.entity.RealTimeResultsEntity;
import com.calabar.util.HttpClientPost;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import java.util.*;

/**
 * <p/>
 * <li>Description: 东锅实时查询接口实现</li>
 * <li>@author: zijian.wu</li>
 * <li>Date: 2018/4/8 9:10</li>
 */
@Repository
public class RealTimeQuery implements IRealTimeQuery {
    /**
     * 查询子系统编码的对象
     */
    @Autowired
    private QuerySubStdCode querySubStdCode;

    /**
     * 查询最后一条数据opentsdb的URL
     */
    @Value("${opentsdb.url.query-last}")
    private String URL_LAST;

    /**
     * 时序数据库的PLANT plt_code
     */
    private final static String PLANT_TAG_KEY = "plt_code";

    /**
     * 时序数据库的SET set_code
     */
    private final static String SET_TAG_KEY = "set_code";

    /**
     * 时序数据库存储的原始值后缀
     */
    private final static String VALUE_SUFFIX = "_src_value";

    /**
     * 时序数据库存储的原始质量标签后缀
     */
    private final static String QUALITY_SUFFIX = "_src_data_quality";

    /**
     * 时序数据库BackScan时间范围
     */
    private final static int BACK_SCAN = 24;

    @Override
    public String realTimeQuery(List<String> stdCodes, String pltCode, String setCode) throws Exception {

        //查询子系统编码
        Map<String, String> subMapStd = querySubStdCode.findSubMapStd(stdCodes);
        List<String> subStdCodes = new ArrayList<>();
        for (String subStdCode : subMapStd.keySet()) {
            subStdCodes.add(subStdCode);
        }

        //标签（电厂编码）
        Map<String, String> tag = new HashMap<>();

        tag.put(PLANT_TAG_KEY, pltCode);
        tag.put(SET_TAG_KEY, setCode);

        //查询测点指标值
        List<Map<String, Object>> valueQueriesList = new ArrayList<>();
        //查询质量标签
        List<Map<String, Object>> qualityQueriesList = new ArrayList<>();
        for (String subStdCode : subStdCodes) {
            //值
            Map<String, Object> valueQuery = new HashMap<>();
            valueQuery.put("metric", subStdCode + VALUE_SUFFIX);
            valueQuery.put("tags", tag);
            valueQueriesList.add(valueQuery);
            //质量标签
            Map<String, Object> qualityQuery = new HashMap<>();
            qualityQuery.put("metric", subStdCode + QUALITY_SUFFIX);
            qualityQuery.put("tags", tag);
            qualityQueriesList.add(qualityQuery);
        }

        //剩余查询条件
        Map<String, Object> query = new HashMap<>();
        query.put("queries", valueQueriesList);
        query.put("resolveNames", true);
        query.put("backScan", BACK_SCAN);

        //值查询转为Json字符串

        String valueQueriesJson = JSON.toJSONString(query, SerializerFeature.DisableCircularReferenceDetect);

        //查询返回值结果
        String valueResult = HttpClientPost.post(URL_LAST, valueQueriesJson);

        //质量标签查询转为Json字符串
        query.put("queries", qualityQueriesList);

        String qualityQueriesJson = JSON.toJSONString(query, SerializerFeature.DisableCircularReferenceDetect);

        //查询返回质量标签结果
        String qualityResult = HttpClientPost.post(URL_LAST, qualityQueriesJson);

        String resultsStr = null;
        // 结果不为空转为组装返回结果json串
        if (StringUtils.isNotEmpty(valueResult) || StringUtils.isNotEmpty(qualityResult)) {
            //值转为json数组
            JSONArray valueResultsArr = JSON.parseArray(valueResult);
            //质量标签转为json数组
            JSONArray qualityResultsArr = JSON.parseArray(qualityResult);

            //声明返回数据
            Map<String, Object> returnData = new LinkedHashMap<>();

            //向返回数据加入标签信息
            returnData.put("pltCode", pltCode);
            returnData.put("setCode", setCode);

            //查询所有测点结果
            List<RealTimeResultsEntity> results = new ArrayList<>();

            //数据组装
            for (int i = 0; i < valueResultsArr.size(); i++) {
                RealTimeResultsEntity realTimeResultsEntity = new RealTimeResultsEntity();
                JSONObject singleValue = valueResultsArr.getJSONObject(i);
                //更改测点编码组装数据
                String subStdCode = singleValue.get("metric").toString().split("_")[0];
                //子系统编码转成标准编码
                realTimeResultsEntity.setStdCode(subMapStd.get(subStdCode));
                //取出时间戳组装数据
                realTimeResultsEntity.setTimestamp(Long.parseLong(singleValue.get("timestamp").toString()));
                //取出值组装数据
                realTimeResultsEntity.setValue(Float.parseFloat(singleValue.get("value").toString()));

                //质量标签组装
                if (qualityResultsArr != null && qualityResultsArr.size() > 0) {
                    for (int j = 0; j < qualityResultsArr.size(); j++) {
                        JSONObject singleQuality = qualityResultsArr.getJSONObject(i);

                        //匹配测点对应的质量标签(通过下滑线分割，取开头,指标名相等，时间戳相等)
                        if (subStdCode.equals(singleQuality.get("metric").toString().split("_")[0])
                                || singleValue.getLongValue("timestamp") == singleQuality.getLongValue("timestamp")) {
                            realTimeResultsEntity.setQuality(Float.parseFloat(singleQuality.get("value").toString()));
                            break;
                        }
                    }
                }
                results.add(realTimeResultsEntity);
            }
            returnData.put("results", results);
            resultsStr = JSON.toJSONString(returnData);
        }

        return resultsStr;
    }
}
